package queue;

import array.Array;

public class LoopQueue <E> implements Queue<E>{
	private E[] data;
	private int front;
	private int tail;
	private int size;
	
	public LoopQueue(int capacity) {
		data = (E[])new Object[capacity+1];
		front = 0;
		tail = 0;
		size = 0;
	}
	
	public LoopQueue() {
		this(10);
	}

	@Override
	public void enqueue(E e) {
		//入队
		if((tail + 1) % data.length == front) {
			resize(data.length * 2);
		}
		data[tail] = e;
		tail = (tail + 1) % data.length;
		size++;
	}

	@Override
	public E dequeue() {
		//出队
		if(isEmpty())
			throw new IllegalArgumentException();
		E e = data[front];
		data[front] = null;
		front = (front + 1) % data.length;
		size--;
		//如果使用的小于四分之一，那么久缩减一半容量数组。
		if(size == getCapacity()/4 && getCapacity()/2 != 0)
			resize(data.length / 2);
		return e;
	}

	@Override
	public E getFront() {
		if(isEmpty())
			throw new IllegalArgumentException();
		return data[front];
	}

	@Override
	public int getSize() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		
		return front == tail;
	}
	
	public void resize(int newCapacity) {
		
		E[] newData = (E[])new Object[newCapacity + 1];
		for(int i = 0 ; i < size ; i++) {
			newData[i] = data[(i + front) % data.length];
		}
		//XXX 需要改进的功能
		//FIXME 需要修改的地方
		data = newData;
		front = 0;
		tail = size;
	}
	
	public int getCapacity() {
		return data.length - 1;
	}
	
	@Override
	public String toString() {
		StringBuilder res = new StringBuilder();
		res.append("LoopQueue: size:"+size+",capacity:"+getCapacity());
		res.append("front:[");
		for(int i = front ; i != tail ; i = (i+1)%data.length) {
			res.append(data[i]);
			if((i+1)%getCapacity() != tail) {
				res.append(",");
			}
		}
		res.append("]tail");
		return res.toString();
	}

}
